#include <stdio.h>
#include <iostream>
#include <string>
#include <sstream>
#include <stdlib.h>
#include <vector>

#define USE_INDEX_INSTEAD_OF_NUM 0

using namespace std;

int M,N;


string convertInt(int number);
string generate_rule(int i, int j, int k, int l);
string index_converter(int a, int b);

int main(int argc, char *argv[])
{

    if (argc < 3)
    {
      cout << "provide M an N as arguments please." <<endl;
      return -1;
    }

    M=atoi(argv[1]); // number of rows
    N=atoi(argv[2]); // number of columns
    
    string havij;
    havij = convertInt(M*N)+"\n\n";

    for (int i=0;i<M*N;i++)
        havij=havij+convertInt(M*N) + " ";
    havij=havij+"\n\n";

    int neighbours[2][4]={  {-1, 0, 0, 1},\
                            { 0,-1, 1, 0}};
    int k, l;

    for (int i=0; i<M;i++)
    {
        for(int j=0;j<N;j++)
        {
            //(k,l) = neighbours(i,j,M,N)
            for(int kk=0;kk<4;kk++)
            {
                k=i+neighbours[0][kk];
                l=j+neighbours[1][kk];
                if (k < 0 || k ==M || l<0 || l==N)
                    continue;
                string tstr= generate_rule(i,j,i+neighbours[0][kk],j+neighbours[1][kk]);
                havij=havij+tstr;
            
            }
        }
    }
    havij=havij+"\nGOAL ";
    for (int i=0; i<M;i++)
    {
        for(int j=0;j<N;j++)
        {
            havij=havij+ index_converter(i,j);
        }
    }
    havij=havij+"\n";
    cout << havij;


}

string generate_rule(int a, int b, int c, int d) //i, j, k, l
{
    //a++;b++;c++;d++;
    string tstr="";
    string tstr2;
    for(int ii=1;ii<M*N;ii++)
    {
        tstr=tstr+index_converter(a,b);
        tstr2=index_converter(c,d);
        for (int jj=1;jj<M*N;jj++)
        {
            if(ii==jj)
            {
                tstr=tstr+index_converter(c,d);
                tstr2=tstr2+index_converter(a,b);
            }
            else
            {
                tstr=tstr+"- ";
                tstr2=tstr2+"- ";
            }
        }
        tstr=tstr+"=> "+tstr2+"\n";
    }
    return tstr;
}

string index_converter(int a, int b)
{
	if(USE_INDEX_INSTEAD_OF_NUM==1)
	{
		return convertInt(a)+","+convertInt(b)+" ";
	}
	return convertInt(a*N+b)+" ";
}

string convertInt(int number)
{
   ostringstream ss;//create a stringstream
   ss << number;//add number to the stream
   return ss.str();//return a string with the contents of the stream
}

/*
 * Generates the dual representation for MxN-puzzle
 * Originally Written by Meysam Bastani
 * Modified by Shahab Jabbari
*/
